package it.uniroma2.dtk.op.convolution;

import it.uniroma2.util.vector.VectorComposer;

import java.util.Arrays;

public class ShuffledCircularConvolution extends CircularConvolution {

	@Override
	public double[] op(double[] x, double[] y) {
		if (x == null)
			return y;
		else if (y == null)
			return x;
		if (fft == null)
			return shuffledConvolutionBasic(x, y);
		else
			return shuffledConvolutionFFT(x, y);
	}
	
	public double[] shuffledConvolutionBasic(double[] firstVector, double[] secondVector) {
		int size = firstVector.length;
		double[] result = new double[size];
		Arrays.fill(result, 0);
		for (int i=0; i<size; i++)
			for (int j=0; j<size; j++) {
				int k = (i-j) < 0 ? (i-j+size) : i-j;
				if (permutation1[j] >= 0) {
					if (permutation2[k] >= 0)
						result[i] += firstVector[permutation1[j]] * secondVector[permutation2[k]];
					else
						result[i] += firstVector[permutation1[j]] * -secondVector[-permutation2[k]];
				}
				else {
					if (permutation2[k] >= 0)
						result[i] += -firstVector[-permutation1[j]] * secondVector[permutation2[k]];
					else
						result[i] += -firstVector[-permutation1[j]] * -secondVector[-permutation2[k]];
				}
			}
		return result;
	}
	
	public double[] shuffledConvolutionFFT(double[] firstVector, double[] secondVector) {
		return circularConvolutionFFT(VectorComposer.shuffle(firstVector, permutation1), VectorComposer.shuffle(secondVector, permutation2));
	}
}
